package com.hbk.codemaker;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.ScrollPaneConstants;
import javax.swing.ScrollPaneLayout;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.apache.commons.io.FileUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.hbk.programe.Field;
import com.hbk.programe.Modular;
import com.hbk.programe.Node;

public class MainFrame extends JFrame {
	
	private int SIDER_WIDTH=250;
	
	private int BORDER_WIDTH=50;
	
	private Component lastFocusComponent;
	
	JScrollPane centerPanel;
	
	private JPanel pojoPanel;

	private ClazzPanel clazzPanel;

	private FieldsPanel fieldsPanel;
	
	private JButton addField;
	
	private MethodsPanel methodsPanel;
	
	private JButton addMethod;

	private List<Modular> pojos = new ArrayList<>();

	private Modular current;

	public MainFrame() throws Exception {
		setTitle("CodeMaker 1.1");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(1400, 600);
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		int x = (int) (toolkit.getScreenSize().getWidth() - getWidth()) / 2;
		int y = (int) (toolkit.getScreenSize().getHeight() - getHeight()) / 2;
		setLocation(x, y);

		clazzPanel = new ClazzPanel(getWidth());

		fieldsPanel = new FieldsPanel(getWidth(),this);
		
		addField = new JButton(new ImageIcon("lib/images/add.png"));
		addField.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				fieldsPanel.addField();
			}
		});
		
		methodsPanel = new MethodsPanel(getWidth(),this);
		
		addMethod = new JButton(new ImageIcon("lib/images/add.png"));
		addMethod.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				methodsPanel.addMethod();
			}
		});

		//数据加载
		File dir = new File("src/main/resources/modular/json/dms");
		File[] files = dir.listFiles();
		for (File f : files) {
			String json = FileUtils.readFileToString(f, "UTF-8");
			Modular pojo = JSON.parseObject(json, new TypeReference<Modular>() {
			});
			pojos.add(pojo);
		}
		
		//JTree加载
		ArrayList<DefaultMutableTreeNode> treeData = new ArrayList<DefaultMutableTreeNode>();
		for (Modular pojo : pojos) {
			DefaultMutableTreeNode clazz = new DefaultMutableTreeNode(new Node("", pojo.getClazz(), ""));
			for (Field field : pojo.getFields()) {
				clazz.add(new DefaultMutableTreeNode(new Node(pojo.getClazz(), field.getType(), field.getName())));
			}
			treeData.add(clazz);
		}

		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
		for (DefaultMutableTreeNode node : treeData) {
			root.add(node);
		}
		JTree tree = new JTree(root);
		tree.setFont(new Font("SansSerif", 0, 24));
		tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {

			@Override
			public void valueChanged(TreeSelectionEvent e) {
				DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
				if (selectedNode != null) {
					Node node = ((Node) selectedNode.getUserObject());
					copy(node);
				}
			}
		});
		tree.setBackground(new Color(247, 247, 247));
		tree.setCellRenderer(new NodeRenderer());
		TreeNode node = (TreeNode) tree.getModel().getRoot();
		expandAll(tree,new TreePath(node),true);
		//tree面板
		JPanel treePanel = new JPanel();
		treePanel.setLayout(new BorderLayout());
		treePanel.add(tree, BorderLayout.CENTER);
		treePanel.setPreferredSize(new Dimension(SIDER_WIDTH, 0));
		//左侧面板
		JScrollPane siderPanel = new JScrollPane(treePanel);
		siderPanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		siderPanel.setLayout(new ScrollPaneLayout());
		
		//pojo面板
		pojoPanel = new JPanel();
		pojoPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
		pojoPanel.setPreferredSize(new Dimension(getWidth()-SIDER_WIDTH*2-BORDER_WIDTH, getHeight()));
		pojoPanel.add(clazzPanel);
		pojoPanel.add(fieldsPanel);
		pojoPanel.add(methodsPanel);
		//中间面板
		centerPanel = new JScrollPane(pojoPanel);
		centerPanel.setLayout(new ScrollPaneLayout());
		
		//常用词面板
		JTabbedPane tabspane = new JTabbedPane();
		tabspane.setPreferredSize(new Dimension(SIDER_WIDTH, 0));
		
		//逻辑符号
		JPanel tab1 = new JPanel();
		String logic[]= {"\r\n","%s",">>","<<","foreach ","=","+","-","*","/","if ","==","!=",">=","<=",">","<","new ","save ","update ","delete ","get ","find ","query "};
		tab1.setLayout(new GridLayout(8, 3));
		for (String text : logic) {
			JButton button=new JButton(text);
			button.addActionListener(new ButtonActionListener(text));
			tab1.add(button);
		}
		
		//DAO
		JPanel tab2 = new JPanel();
		//翻译
		JPanel tab3 = new JPanel();
		
		tabspane.addTab("逻辑符号", tab1);
		tabspane.addTab("DAO", tab2);
		tabspane.addTab("翻译", tab3);
		
		
		//底层面板
		JPanel jpanel = new JPanel();
		jpanel.setBackground(Color.WHITE);
		jpanel.setLayout(new BorderLayout());
		jpanel.add(siderPanel, BorderLayout.WEST);
		jpanel.add(centerPanel, BorderLayout.CENTER);
		jpanel.add(tabspane, BorderLayout.EAST);
		getContentPane().add(jpanel);
		
		addComponentListener(new ComponentListener() {

			@Override
			public void componentShown(ComponentEvent e) {
				
			}

			@Override
			public void componentResized(ComponentEvent e) {
				repaint();
			}

			@Override
			public void componentMoved(ComponentEvent e) {
				
			}

			@Override
			public void componentHidden(ComponentEvent e) {
				
			}
		});

		setVisible(true);
	}

	public void loadPojo(String clazz) {
		for (Modular modular : pojos) {
			if (modular.getClazz().equals(clazz)) {
				current = modular;
			}
		}
		if (current != null) {
			clazzPanel.setClazz(current.getClazz());
			clazzPanel.setTable(current.getTable());
			clazzPanel.setComment(current.getComment());
			clazzPanel.setAlias(current.getAlias());
			
			fieldsPanel.setFields(current.getFields());
			
			methodsPanel.setMethods(current.getMethods());
		}
		repaint();
	}
	
	public void copy(Node node) {
		Component component=getLastFocusComponent();
		if(component!=null) {
			if(component instanceof FieldPanel) {
				String text = node.getClazz() + "." + node.getField();
				String[] clazzField=text.split("[.]");
				for(Modular pojo:pojos) {
					if(pojo.getClazz().equals(clazzField[0])) {
						for(Field field:pojo.getFields()) {
							if(field.getName().equals(clazzField[1])) {
								((FieldPanel)component).setField(field);
							}
						}
					}
				}
			}else if(component instanceof JTextArea) {
				String text = "";
				if (node.isClass()) {
					text = node.getType();
				} else {
					text = node.getClazz() + "." + node.getField();
				}
				JTextArea area=((JTextArea)component);
				if(area.getText().contains("%s")) {
					area.setText(String.format(area.getText(), text));
				}else {
					area.setText(area.getText()+text);
				}
			}
		}
	}

	@Override
	public void repaint() {
		clazzPanel.repaint(getWidth()-SIDER_WIDTH*2-BORDER_WIDTH);
		fieldsPanel.repaint(getWidth()-SIDER_WIDTH*2-BORDER_WIDTH);
		methodsPanel.repaint(getWidth()-SIDER_WIDTH*2-BORDER_WIDTH);
		pojoPanel.setPreferredSize(new Dimension(getWidth()-SIDER_WIDTH*2-BORDER_WIDTH, clazzPanel.getHeight()+fieldsPanel.getHeight()+methodsPanel.getHeight()+BORDER_WIDTH));
		pojoPanel.repaint();
		centerPanel.repaint();
		super.repaint();
	}

	public Component getLastFocusComponent() {
		return lastFocusComponent;
	}

	public void setLastFocusComponent(Component lastFocusComponent) {
		this.lastFocusComponent = lastFocusComponent;
	}
	
	private void expandAll(JTree tree, TreePath parent, boolean expand) {
		TreeNode node = (TreeNode) parent.getLastPathComponent();

		if (node.getChildCount() > 0) {
			for (Enumeration e = node.children(); e.hasMoreElements();) {
				TreeNode n = (TreeNode) e.nextElement();
				TreePath path = parent.pathByAddingChild(n);
				expandAll(tree, path, expand);

			}
		}
		if (expand) {
			tree.expandPath(parent);
		} else {
			tree.collapsePath(parent);
		}
	}
	
	class ButtonActionListener implements ActionListener{
		
		private String text;
		
		public ButtonActionListener(String text) {
			this.text=text;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			Component component=getLastFocusComponent();
			JTextArea area=((JTextArea)component);
			if(area.getText().contains("%s")) {
				area.setText(String.format(area.getText(), text));
			}else {
				area.setText(area.getText()+text);
			}
		}
		
	}
}
